import { _decorator, Component, EventKeyboard, Input, input, KeyCode, Vec2 } from 'cc';
import { GlobalEventBus } from '../core/EventBus';

const { ccclass, property } = _decorator;

export const DEBUG_DRAW = false; // UI-only debug flag; keep visuals disabled by default.

export interface InputState {
  move: Vec2;
  interact: boolean;
  throwHeld: boolean;
}

/**
 * 输入桥接层，统一触屏摇杆与键鼠/手柄状态。
 */
@ccclass('InputBridge')
export class InputBridge extends Component {
  @property
  public enableKeyboard = true;

  private move = new Vec2();
  private interact = false;
  private throwHeld = false;
  private static active: InputBridge | null = null;

  onEnable() {
    if (this.enableKeyboard) {
      input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this);
      input.on(Input.EventType.KEY_UP, this.onKeyUp, this);
    }
    InputBridge.active = this;
  }

  onDisable() {
    if (this.enableKeyboard) {
      input.off(Input.EventType.KEY_DOWN, this.onKeyDown, this);
      input.off(Input.EventType.KEY_UP, this.onKeyUp, this);
    }
    if (InputBridge.active === this) {
      InputBridge.active = null;
    }
  }

  update(dt: number) {
    // Always emit movement snapshot for HUD/overlay listeners (visual debug is off by default).
    GlobalEventBus.emit('input/move', { x: this.move.x, y: this.move.y } as any);
  }

  updateTouch(moveVec: Vec2, interact: boolean, throwHeld: boolean): void {
    this.move.set(moveVec.x, moveVec.y);
    this.interact = interact;
    this.throwHeld = throwHeld;
  }

  snapshot(): InputState {
    return {
      move: this.move.clone(),
      interact: this.interact,
      throwHeld: this.throwHeld,
    };
  }

  // Spec helpers: module-level accessors for tests and simple scripts
  getMoveVec(): Vec2 {
    return this.move.clone();
  }

  getActionState(): { interact: boolean; throw: boolean } {
    return { interact: this.interact, throw: this.throwHeld };
  }

  private onKeyDown(event: EventKeyboard) {
    switch (event.keyCode) {
      case KeyCode.KEY_W:
      case KeyCode.ARROW_UP:
        this.move.y = 1;
        break;
      case KeyCode.KEY_S:
      case KeyCode.ARROW_DOWN:
        this.move.y = -1;
        break;
      case KeyCode.KEY_A:
      case KeyCode.ARROW_LEFT:
        this.move.x = -1;
        break;
      case KeyCode.KEY_D:
      case KeyCode.ARROW_RIGHT:
        this.move.x = 1;
        break;
      case KeyCode.KEY_J: // interact placeholder
      case KeyCode.KEY_F: // keep legacy binding
        this.interact = true;
        break;
      case KeyCode.KEY_K: // throw placeholder
      case KeyCode.SPACE: // keep legacy binding
        this.throwHeld = true;
        break;
      default:
        break;
    }
    this.limitMoveVector();
  }

  private onKeyUp(event: EventKeyboard) {
    switch (event.keyCode) {
      case KeyCode.KEY_W:
      case KeyCode.ARROW_UP:
      case KeyCode.KEY_S:
      case KeyCode.ARROW_DOWN:
        this.move.y = 0;
        break;
      case KeyCode.KEY_A:
      case KeyCode.ARROW_LEFT:
      case KeyCode.KEY_D:
      case KeyCode.ARROW_RIGHT:
        this.move.x = 0;
        break;
      case KeyCode.KEY_J:
      case KeyCode.KEY_F:
        this.interact = false;
        break;
      case KeyCode.KEY_K:
      case KeyCode.SPACE:
        this.throwHeld = false;
        break;
      default:
        break;
    }
    this.limitMoveVector();
  }

  private limitMoveVector() {
    if (this.move.lengthSqr() > 1) {
      this.move.normalize();
    }
  }
}

// Top-level exports per spec
export function getMoveVec(): Vec2 {
  return (InputBridge.active?.getMoveVec() ?? new Vec2());
}

export function getActionState(): { interact: boolean; throw: boolean } {
  return (InputBridge.active?.getActionState() ?? { interact: false, throw: false });
}

export default InputBridge;
